home *** CD-ROM | disk | FTP | other *** search
- /* ------------- listbox.c ------------ */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "dflat.h"
-
- static void near writeselection(WINDOW, int, int, RECT *);
- static void near change_selection(WINDOW, int);
- static int near selection_in_window(WINDOW, int);
-
-
- int ListBoxProc(WINDOW wnd, MESSAGE msg, PARAM p1, PARAM p2)
- {
- int rtn;
- static int py = -1;
- int my = (int) p2 - GetTop(wnd);
-
- if (my >= wnd->wlines-wnd->wtop)
- my = wnd->wlines - wnd->wtop;
-
- switch (msg) {
- case CREATE_WINDOW:
- rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
- wnd->selection = -1;
- return rtn;
- case ADDTEXT:
- p2 = wnd->wlines == wnd->selection;
- break;
- case CLEARTEXT:
- wnd->selection = -1;
- break;
- case SCROLL:
- rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
- if (!selection_in_window(wnd, wnd->selection)) {
- if (p1)
- PostMessage(wnd, LB_SELECTION, wnd->selection+1, FALSE);
- else
- PostMessage(wnd, LB_SELECTION, wnd->selection-1, FALSE);
- }
- else
- writeselection(wnd, wnd->selection, TRUE, NULL);
- return rtn;
- case KEYBOARD:
- if (WindowMoving || WindowSizing)
- break;
- switch ((int) p1) {
- case UP:
- if (wnd->selection > 0) {
- if (wnd->selection == wnd->wtop) {
- writeselection(wnd, wnd->selection, FALSE, NULL);
- --wnd->selection;
- rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
- PostMessage(wnd, LB_SELECTION, wnd->selection, FALSE);
- }
- else {
- int newsel = wnd->selection-1;
- if (wnd->wlines == ClientHeight(wnd))
- while (*TextLine(wnd, newsel) == LINE)
- --newsel;
- PostMessage(wnd, LB_SELECTION, newsel, FALSE);
- }
- }
- return TRUE;
- case DN:
- if (wnd->selection < wnd->wlines-1) {
- if (wnd->selection == wnd->wtop+ClientHeight(wnd)-1) {
- writeselection(wnd, wnd->selection, FALSE, NULL);
- wnd->selection++;
- rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
- PostMessage(wnd, LB_SELECTION, wnd->selection, FALSE);
- }
- else {
- int newsel = wnd->selection+1;
- if (wnd->wlines == ClientHeight(wnd))
- while (*TextLine(wnd, newsel) == LINE)
- newsel++;
- PostMessage(wnd, LB_SELECTION, newsel, FALSE);
- }
- }
- return TRUE;
- case PGUP:
- case PGDN:
- rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
- PostMessage(wnd, LB_SELECTION, wnd->wtop, FALSE);
- return rtn;
- case HOME:
- rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
- PostMessage(wnd, LB_SELECTION, 0, FALSE);
- return rtn;
- case END:
- rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
- PostMessage(wnd, LB_SELECTION, wnd->wlines-1, FALSE);
- return rtn;
- case '\r':
- if (wnd->selection != -1) {
- WINDOW pwnd = GetParent(wnd);
- SendMessage(wnd, LB_SELECTION, wnd->selection, TRUE);
- SendMessage(pwnd, LB_CHOOSE, wnd->selection, 0);
- }
- return TRUE;
- default:
- break;
- }
- break;
- case BUTTON_RELEASED:
- py = -1;
- break;
- case LEFT_BUTTON:
- if (!(WindowMoving || WindowSizing)) {
- RECT rc = ClientRect(wnd);
- if (!InsideRect(p1, p2, rc))
- break;
- if (my != py) {
- int newsel = wnd->wtop+my-1;
- if (*TextLine(wnd, newsel) != LINE)
- SendMessage(wnd, LB_SELECTION, newsel, TRUE);
- py = my;
- }
- return TRUE;
- }
- break;
- case DOUBLE_CLICK:
- BaseWndProc(LISTBOX, wnd, msg, p1, p2);
- if (!(WindowMoving || WindowSizing))
- SendMessage(GetParent(wnd), LB_CHOOSE, wnd->selection, 0);
- return TRUE;
- case LB_SETSELECTION:
- change_selection(wnd, (int) p1);
- return TRUE;
- case LB_SELECTION: {
- WINDOW pwnd = GetParent(wnd);
- CLASS class = GetClass(pwnd);
- change_selection(wnd, (int) p1);
- if (class != LISTBOX && DerivedClass(class) != LISTBOX)
- SendMessage(GetParent(wnd), LB_SELECTION, wnd->selection, 0);
- return TRUE;
- }
- case LB_CURRENTSELECTION:
- return wnd->selection;
- case LB_GETTEXT:
- if ((int)p2 != -1) {
- char *cp1 = (char *)p1;
- char *cp2 = TextLine(wnd, (int)p2);
- while (cp2 && *cp2 && *cp2 != '\n')
- *cp1++ = *cp2++;
- *cp1 = '\0';
- }
- return TRUE;
- case PAINT:
- if (isVisible(wnd)) {
- rtn = BaseWndProc(LISTBOX, wnd, msg, p1, p2);
- writeselection(wnd, wnd->selection, TRUE, (RECT *)p1);
- return rtn;
- }
- break;
- default:
- break;
- }
- return BaseWndProc(LISTBOX, wnd, msg, p1, p2);
- }
-
- static int near selection_in_window(WINDOW wnd, int sel)
- {
- return (wnd->wlines && sel >= wnd->wtop && sel < wnd->wtop+ClientHeight(wnd));
- }
-
- static void near writeselection(WINDOW wnd, int sel, int reverse, RECT *rc)
- {
- if (selection_in_window(wnd, sel))
- WriteTextLine(wnd, rc, sel-wnd->wtop, reverse);
- }
-
- static void near change_selection(WINDOW wnd, int sel)
- {
- if (sel != wnd->selection) {
- writeselection(wnd, wnd->selection, FALSE, NULL);
- wnd->selection = sel;
- writeselection(wnd, sel, TRUE, NULL);
- }
- }